package cn.iocoder.yudao.module.contract.webservice;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.contract.controller.admin.company.vo.CompanyRespVO;
import cn.iocoder.yudao.module.contract.dal.dataobject.basicData.BasicSupplierDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.client.ClientDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.contractTemplate.ContractTemplateDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.exportContract.ExportContractDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.order.OrderDetailsDO;
import cn.iocoder.yudao.module.contract.dal.dataobject.orderContract.OrderContractDO;
import cn.iocoder.yudao.module.contract.dal.mysql.order.OrderDetailsMapper;
import cn.iocoder.yudao.module.contract.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.contract.enums.OrderStatusEnum;
import cn.iocoder.yudao.module.contract.service.basicData.BasicSupplierService;
import cn.iocoder.yudao.module.contract.service.client.ClientService;
import cn.iocoder.yudao.module.contract.service.contractTemplate.ContractTemplateService;
import cn.iocoder.yudao.module.contract.service.exportContract.ExportContractService;
import cn.iocoder.yudao.module.contract.service.order.OrderService;
import cn.iocoder.yudao.module.contract.service.orderContract.OrderContractService;
import cn.iocoder.yudao.module.contract.webservice.holders.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.xml.namespace.QName;
import javax.xml.rpc.holders.StringHolder;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.hibernate.validator.internal.util.Contracts.assertNotNull;

@Component
@Slf4j
public class ContractWebService {

    @Resource
    private OrderService orderService;
    @Resource
    private OrderDetailsMapper orderDetailsMapper;
    @Resource
    private ClientService clientService;
    @Resource
    private OrderContractService orderContractService;
    @Resource
    private BasicSupplierService basicSupplierService;
    @Resource
    private ExportContractService exportContractService;


    public String getOrderList(String vbeln) {
        log.info("订单同步WebService开始,vbeln：{}",vbeln);
        ZWB_JS_BindingStub binding;
        int total = 0;
        int add=0;
        int update=0;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null");
            // Time out after a minute
            binding.setTimeout(60000);
            // Test operation
            TABLE_OF_ZJS004HHolder otHEAD = new TABLE_OF_ZJS004HHolder();
            TABLE_OF_ZJS004IHolder otItem = new TABLE_OF_ZJS004IHolder();
            StringHolder oMess = new StringHolder();
            StringHolder oType = new StringHolder();
            binding.ZFM_JS_004( vbeln, otHEAD, otItem, oMess, oType);
            log.info("订单同步WebService-otHEAD:{}",JSONObject.toJSONString(otHEAD.value));
            log.info("订单同步WebService-otItem:{}",JSONObject.toJSONString(otItem.value));
            log.info("订单同步WebService-oMess:{}",oMess);
            log.info("订单同步WebService-oType:{}",oType);
            List<OrderDO> orderDOList = JSONArray.parseArray(JSONObject.toJSONString(otHEAD.value),OrderDO.class);
            List<OrderDetailsDO> detailsList = JSONArray.parseArray(JSONObject.toJSONString(otItem.value),OrderDetailsDO.class);
//            log.info("订单同步WebService-orderDOList{}", JSONObject.toJSONString(orderDOList));
//            log.info("订单同步WebService-detailsList{}", JSONObject.toJSONString(detailsList));
            Map<String, List<OrderDetailsDO>> groupDetailsList = detailsList.stream()
                    .collect(Collectors.groupingBy(OrderDetailsDO::getVbeln));
            total = orderDOList.size();
            for(OrderDO orderDO : orderDOList){
                OrderDO order = orderService.getOne(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getVbeln,orderDO.getVbeln()),false);
                if(order!=null) {
                    if(!"Y4".equals(orderDO.getHtdymb())){
                        //非出口合同-作废时更新
                        if (!"3".equals(order.getZzxshtzt())) {
                            log.info("销售凭证：{}已存在并非作废状态，重新通知{}", orderDO.getVbeln(),order.getZzxshtzt());
                            OrderContractDO orderContract = orderContractService.getOne(new LambdaQueryWrapper<OrderContractDO>().eq(OrderContractDO::getOrderId,orderDO.getId()),false);
                            if(orderContract == null){
                                orderContract = new OrderContractDO();
                            }
                            pushOrderStatus(orderDO.getVbeln(),order.getZzxshtzt(),orderContract);
                            continue;
                        } else {
                            update = update + 1;
                            orderDO.setId(order.getId());
                        }
                    }else{
                        //出口合同-未生成合同时可更新
                        if ("1".equals(order.getStatus())) {
                            log.info("出口合同-销售凭证：{}已生成合同，重新通知{}", orderDO.getVbeln(),order.getZzxshtzt());
                            ExportContractDO exportContractDO = exportContractService.getOne(new QueryWrapper<ExportContractDO>().like("CONCAT(',',vbelns,',')",","+orderDO.getVbeln()+",").ne("status","3"),false);
                            if(exportContractDO == null){
                                //未生成合同时通知已接收数据
                                exportContractDO = new ExportContractDO();
                                exportContractDO.setStatus("1");
                            }
                            pushOrderStatus(orderDO.getVbeln(),exportContractDO);
                            continue;
                        } else {
                            update = update + 1;
                            orderDO.setId(order.getId());
                        }
                    }
                }
                orderService.saveOrUpdate(orderDO);
                List<OrderDetailsDO> list = groupDetailsList.get(orderDO.getVbeln());
                if(list!=null){
                    list.stream().forEach(detail -> {
                        detail.setOrderId(orderDO.getId());
                    });
                    if(order!=null){
                        orderDetailsMapper.deleteByOrderId(order.getId());
                    }
                    orderDetailsMapper.insertBatch(list);
                }
                if(!"Y4".equals(orderDO.getHtdymb())){
                    //异步创建合同
                    orderContractService.createOrderContract(orderDO);
                    add = add+1;
                }else{
                    ExportContractDO exportContractDO = exportContractService.getOne(new QueryWrapper<ExportContractDO>().like("CONCAT(',',vbelns,',')",","+orderDO.getVbeln()+",").ne("status","3"),false);
                    if(exportContractDO == null){
                        //未生成合同时通知已接收数据
                        exportContractDO = new ExportContractDO();
                        exportContractDO.setStatus("1");
                        pushOrderStatus(orderDO.getVbeln(),exportContractDO);
                    }
                }
            }
            log.info("订单同步WebService结束");
            return StrUtil.format("同步成功-共{}条,更新{}条,新增{}条。",total,update,add);
        }
        catch (Exception e) {
            log.error("订单WebService调用异常",e);
            return StrUtil.format("同步失败-{}",e.getMessage());
        }
    }


    public String getClient(String endDate,String vbeln) {
        log.info("客户WebService开始,endDate:{},vbeln{}",endDate,vbeln);
        ZWB_JS_BindingStub binding;
        int total = 0;
        int add=0;
        int update=0;
        try {
            binding = (ZWB_JS_BindingStub)
                          new ZWB_JS_ServiceLocator().getZWB_JS();

            assertNotNull(binding,"binding is null");
            binding.setTimeout(60000);
            TABLE_OF_ZSD_JS_004Holder holder = new TABLE_OF_ZSD_JS_004Holder();
            binding.ZFM_JS_005(endDate, vbeln, holder);
            log.info("客户同步WebService-holder:{}",JSONObject.toJSONString(holder.value));
            List<ClientDO> clinetList = JSONArray.parseArray(JSONObject.toJSONString(holder.value),ClientDO.class);
            log.info("客户同步WebService-clinetList{}", JSONObject.toJSONString(clinetList));
            total = clinetList.size();
            for(ClientDO clientDO : clinetList){
                ClientDO client = clientService.getOne(Wrappers.<ClientDO>lambdaQuery().eq(ClientDO::getClientCode,clientDO.getClientCode()),false);
                if(client!=null){
                    clientDO.setId(client.getId());
                    update = update+1;
                }else{
                    add = add+1;
                }
                if(StringUtils.isNotBlank(clientDO.getZmonth())){
                    if("000".equals(clientDO.getZmonth())){
                        clientDO.setZmonth("0");
                    }else{
                        clientDO.setZmonth(clientDO.getZmonth().replace("000",""));
                    }
                }
                clientService.saveOrUpdate(clientDO);
            }
            return StrUtil.format("同步成功-共{}条,修改{}条,新增{}条。",total,update,add);
        }
        catch (Exception e) {
            log.error("客户WebService调用异常",e);
            return StrUtil.format("同步失败-{}",e.getMessage());
        }

    }


    public String getSupplier(String endDate,String vbeln) {
        log.info("供应商WebService开始,endDate:{},vbeln{}",endDate,vbeln);
        ZWB_JS_BindingStub binding;
        int total = 0;
        int add=0;
        int update=0;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();

            assertNotNull(binding,"binding is null");
            binding.setTimeout(60000);
            TABLE_OF_ZSD_JS_009Holder holder = new TABLE_OF_ZSD_JS_009Holder();
            binding.ZFM_JS_009(endDate, vbeln, holder);
            log.info("供应商WebService-holder:{}",JSONObject.toJSONString(holder.value));
            List<BasicSupplierDO> clinetList = JSONArray.parseArray(JSONObject.toJSONString(holder.value), BasicSupplierDO.class);
            log.info("供应商WebService-clinetList{}", JSONObject.toJSONString(clinetList));
            total = clinetList.size();
            for(BasicSupplierDO basicSupplierDO : clinetList){
                BasicSupplierDO client = basicSupplierService.getOne(Wrappers.<BasicSupplierDO>lambdaQuery().eq(BasicSupplierDO::getCode,basicSupplierDO.getCode()),false);
                if(client!=null){
                    basicSupplierDO.setId(client.getId());
                    update = update+1;
                }else{
                    add = add+1;
                }
                basicSupplierService.saveOrUpdate(basicSupplierDO);
            }
            return StrUtil.format("同步成功-共{}条,修改{}条,新增{}条。",total,update,add);
        }
        catch (Exception e) {
            log.error("供应商WebService调用异常",e);
            return StrUtil.format("同步失败-{}",e.getMessage());
        }

    }

    public void pushOrderStatus(String vbeln, ExportContractDO contract){
        String status = contract.getStatus();
//        if("-1".equals(contract.getStatus())){
//            status = "3";
//        }else if("1".equals(contract.getStatus())){
//            status = "2";
//        }else if("2".equals(contract.getStatus())){
//            status = "4";
//        }else {
//            return;
//        }
        ZWB_JS_BindingStub binding;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            ZJS008I[] data = new ZJS008I[1];
            ZJS008I zjs008I = new ZJS008I();
            zjs008I.setVBELN(vbeln);
            zjs008I.setZZXSHTZT(status);
            zjs008I.setZTYPE("");
            zjs008I.setZMESS("");
            data[0] = zjs008I;
            log.info("订单状态推送WebService-param:{}",JSONObject.toJSONString(data));
            ZJS008I[] result = binding.ZFM_JS_008(data);
            log.info("订单状态推送WebService-result:{}",JSONObject.toJSONString(result));
            if("S".equals(result[0].getZTYPE())){
                contract.setIsPushRelease("1");
                contract.setAbnormalCause("");
            }else{
                contract.setIsPushRelease("-1");
                contract.setAbnormalCause(result[0].getZMESS());
            }
            OrderDO order = orderService.getOne(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getVbeln,vbeln),false);
            if(order!=null) {
                OrderDO orderDO = new OrderDO();
                orderDO.setId(order.getId());
                orderDO.setZzxshtzt(status);
                orderDO.setZzxshtztt(OrderStatusEnum.getNameByCode(status));
                orderService.updateById(orderDO);
            }
        }catch (Exception e) {
            log.error("订单状态推送WebService调用异常",e);
            contract.setIsPushRelease("-1");
            contract.setAbnormalCause("调用WebService异常");
        }
    }

    public void pushOrderStatus(String vbeln,String status,OrderContractDO contract){
        ZWB_JS_BindingStub binding;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            ZJS008I[] data = new ZJS008I[1];
            ZJS008I zjs008I = new ZJS008I();
            zjs008I.setVBELN(vbeln);
            zjs008I.setZZXSHTZT(status);
            zjs008I.setZTYPE("");
            zjs008I.setZMESS("");
            data[0] = zjs008I;
            log.info("订单状态推送WebService-param:{}",JSONObject.toJSONString(data));
            ZJS008I[] result = binding.ZFM_JS_008(data);
            log.info("订单状态推送WebService-result:{}",JSONObject.toJSONString(result));
            if("S".equals(result[0].getZTYPE())){
                contract.setIsPushRelease("1");
                contract.setAbnormalCause("");
            }else{
                contract.setIsPushRelease("-1");
                contract.setAbnormalCause(result[0].getZMESS());
            }
            OrderDO order = orderService.getOne(Wrappers.<OrderDO>lambdaQuery().eq(OrderDO::getVbeln,vbeln),false);
            if(order!=null) {
                OrderDO orderDO = new OrderDO();
                orderDO.setId(order.getId());
                orderDO.setZzxshtzt(status);
                orderDO.setZzxshtztt(OrderStatusEnum.getNameByCode(status));
                orderService.updateById(orderDO);
            }
        }catch (Exception e) {
            log.error("订单状态推送WebService调用异常",e);
            contract.setIsPushRelease("-1");
            contract.setAbnormalCause("调用WebService异常");
        }
    }

    public void pushRelease(String vbeln,OrderContractDO contract){
        ZWB_JS_BindingStub binding;
        try {
            binding = (ZWB_JS_BindingStub)
                          new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            StringHolder oMess = new StringHolder();
            StringHolder oType = new StringHolder();
            binding.ZFM_JS_006("",vbeln, oMess, oType);
            log.info("订单释放WebService-oMess:{}",oMess.value);
            log.info("订单释放WebService-oType:{}",oType.value);
            if("S".equals(oType.value)){
                contract.setIsPushRelease("1");
                contract.setAbnormalCause("");
            }else{
                contract.setIsPushRelease("-1");
                contract.setAbnormalCause(oMess.value);
            }
        }catch (Exception e) {
            log.error("客户WebService调用异常",e);
            contract.setIsPushRelease("-1");
            contract.setAbnormalCause("调用WebService异常");
        }
    }

    public boolean pushContractFreeze(String vbeln,OrderContractDO contract){
        ZWB_JS_BindingStub binding;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            StringHolder oMess = new StringHolder();
            StringHolder oType = new StringHolder();
            binding.ZFM_JS_006("Z8",vbeln, oMess, oType);
            log.info("订单冻结WebService-oMess:{}",oMess.value);
            log.info("订单冻结WebService-oType:{}",oType.value);
            if("S".equals(oType.value)){
                contract.setAbnormalCause("");
                return true;
            }else{
                contract.setAbnormalCause(oMess.value);
                return false;
            }
        }catch (Exception e) {
            log.error("客户WebService调用异常",e);
            contract.setAbnormalCause("调用WebService异常");
        }
        return false;
    }

    public boolean pushContractRelease(String vbeln,OrderContractDO contract){
        ZWB_JS_BindingStub binding;
        try {
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            StringHolder oMess = new StringHolder();
            StringHolder oType = new StringHolder();
            binding.ZFM_JS_006("",vbeln, oMess, oType);
            log.info("订单释放WebService-oMess:{}",oMess.value);
            log.info("订单释放WebService-oType:{}",oType.value);
            if("S".equals(oType.value)){
                contract.setAbnormalCause("");
                return true;
            }else{
                contract.setAbnormalCause(oMess.value);
                return false;
            }
        }catch (Exception e) {
            log.error("客户WebService调用异常",e);
            contract.setAbnormalCause("调用WebService异常");
        }
        return false;
    }

    public ZSD_JS_010[] orderShippingStatus(String vbeln){
        ZWB_JS_BindingStub binding;
        try{
            binding = (ZWB_JS_BindingStub)
                    new ZWB_JS_ServiceLocator().getZWB_JS();
            assertNotNull(binding,"binding is null" );
            binding.setTimeout(60000);
            ZSD_JS_010[] data = new ZSD_JS_010[1];
            ZSD_JS_010 zsdJs010 = new ZSD_JS_010(vbeln,"","","","");
            data[0] = zsdJs010;
            log.info("订单状态获取WebService-param:{}",JSONObject.toJSONString(data));
            ZSD_JS_010[] result = binding.ZFM_JS_010(data);
            log.info("订单状态获取WebService-result:{}",JSONObject.toJSONString(result));
            return result;
        }catch (Exception e){
            log.error("订单状态获取客户WebService调用异常",e);
        }
        return null;
    }


    public static void main(String[] args) {
//        List<ZJS004I> list = new ArrayList<>();

        ZJS004I[] a = new ZJS004I[2];
        ZJS004I zjs004H = new ZJS004I();

        zjs004H.setVBELN("1");
        zjs004H.setPOSNR("2");
        zjs004H.setSPART("3");
        zjs004H.setSPARTT("4");
        zjs004H.setZZCPGG("5");
        zjs004H.setMATNR("6");
        zjs004H.setARKTX("7");
        zjs004H.setBISMT("8");
        zjs004H.setKWMENG(new BigDecimal("9"));
        zjs004H.setZYP02(new BigDecimal("11"));
        zjs004H.setCJDJ(new BigDecimal("10"));
        zjs004H.setDDJE(new BigDecimal("12"));
        zjs004H.setDJ("13");
        zjs004H.setZZHTIBZ("14");
        zjs004H.setCPZL("15");
        zjs004H.setZSCPBZ("16");
        zjs004H.setNETWR(new BigDecimal("17"));
        zjs004H.setZZVBELN("18");
        zjs004H.setZZPOSNR("19");
        a[0] = zjs004H;
        a[1] = zjs004H;

        TABLE_OF_ZJS004IHolder otHEAD = new TABLE_OF_ZJS004IHolder(a);
        System.out.println(JSONObject.toJSONString(otHEAD.value));
        List<OrderDetailsDO> orderDOList = JSONArray.parseArray(JSONObject.toJSONString(otHEAD.value),OrderDetailsDO.class);
        System.out.println(JSONObject.toJSONString(orderDOList));
        for(int i=0;i<otHEAD.value.length;i++){
//            OrderDetailsDO orderDetailsDO = BeanUtils.toBean(otHEAD.value[i], OrderDetailsDO.class);
            OrderDetailsDO orderDetailsDO = JSONObject.parseObject(JSONObject.toJSONString(otHEAD.value[i]),OrderDetailsDO.class);
//            list.add(otHEAD.value[i]);
            orderDOList.add(orderDetailsDO);
        }
//        List<OrderDetailsDO> orderDOList = BeanUtils.toBean(Arrays.asList(otHEAD.value), OrderDetailsDO.class);
        System.out.println(JSONObject.toJSONString(orderDOList));


    }
}
